
package com.rt.schedulenew.core.config;

import com.rt.schedulebase.dto.ConfigDto.SysTask;
import com.rt.schedulenew.service.impl.ConfigServiceImpl;
import com.rt.schedulenew.task.DynamicScheduleTask;
import com.rt.schedulenew.utils.base.ConstantsUtil.EhCacheName;
import com.rt.schedulenew.utils.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;

/**
 * 获取和装配自动任务
 */

@Configuration
@EnableScheduling
public class ScheduleTaskConfig implements SchedulingConfigurer {
    private Logger log = LoggerFactory.getLogger(ScheduleTaskConfig.class);
    @Autowired
    private ConfigServiceImpl configServiceImpl;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    // 获取系统任务列表
                    List<SysTask> tasks = configServiceImpl.getTaskList();
                    for (SysTask task : tasks) {
                        // 获取cron 表达式获取的时间，不为空说明执行前一次时间点
                        String cronTime = (String) EhCacheUtil.get(EhCacheName.scheduleTask.name(), task.getMethodName());
                        if (cronTime == null) {
                            cronTime = CronUtil.parseCron(task.getCron());
                            // 如果不是自动预约任务，则缓存任务执行时间
                            if (!task.getMethodName().equals("autoScheduleTask")) {
                                EhCacheUtil.put(EhCacheName.scheduleTask.name(), task.getMethodName(), cronTime);
                            }
                        }
                        // 获取当前时间
                        String currTime = DateUtil.date2Str(new Date(), "yyyy-MM-dd HH:mm");
                        // 当前时间大于表达式计算时间
                        if ("0".equals(task.getState()) && currTime.compareTo(cronTime) >= 0) {
                            Method method = DynamicScheduleTask.class.getDeclaredMethod(task.getMethodName(), null);
                            try {
                                method.invoke(SpringUtil.getBean(DynamicScheduleTask.class));
                                // 清除缓存时间
                                if (!task.getMethodName().equals("autoScheduleTask")) {
                                    EhCacheUtil.remove(EhCacheName.scheduleTask.name(), task.getMethodName());
                                }
                            } catch (Exception ex) {
                                log.error("configureTasks：执行失败" + JsonUtil.toJson(task) + ex.getMessage(), ex);
                            }
                        }
                    }

                } catch (Exception ex) {
                    log.error("configureTasks" + ex.getMessage(), ex);
                }
            }
        };
        // 触发器
        Trigger trigger = triggerContext -> {
            String cron = "0 */1 * * * ?";
            CronTrigger trigger1 = new CronTrigger(cron);
            return trigger1.nextExecutionTime(triggerContext);
        };
        taskRegistrar.addTriggerTask(runnable, trigger);
    }
}
